package com.jar.exercise.io.随机读写;

import org.junit.Test;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 随机访问文件，自带读写方法，该类不算是IO体系中的字类，而是直接继承Object
 * 但是它是IO包中的成员，因为它具备读写功能。
 * 内部封装了一个数组，而且通过指针对数组的元素进行操作。
 * 可以通过getFilePointer获取指针的位置
 * 同时可以通过seek改变指针的位置
 * 其实完成读写的原理就是内部封装了字节输入流和输出流
 * <p>
 * 应用场景：
 * 数据的分段下载，加快下载速度
 */
public class RandomAccessFileDemo {
	public static void main(String[] args) throws IOException {
		String fileName = "D:\\Study\\IDEA\\vue\\Demo\\src\\io\\随机读写\\access.txt";
//        test(fileName);
		seek(fileName);
	}

	public static void test(String fileName) throws IOException {
		/**
		 * 如果文件不存在会创建文件，
		 * 内容存在，会从开头覆盖
		 */
		RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
		raf.write("你好".getBytes());
		raf.write(97);
		raf.close();
	}

	public static void seek(String fileName) throws IOException {
		RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
		raf.seek(raf.length());
		raf.write("插".getBytes());
		raf.close();
	}

	/**
	 * 使用RandomAccessFile实现插入数据到文件效果
	 * 在bbb前面插入***
	 */
	@Test
	public void test1() throws IOException {
		String fileName = "D:\\Study\\IDEA\\vue\\Demo\\src\\io\\随机读写\\插入.txt";
		RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
		byte[] b = new byte[1024];
		StringBuilder sb = new StringBuilder((int) raf.length());
		int len;
		while ((len = raf.read(b)) != -1) {
			sb.append(new String(b, 0, len));
		}
		int bbb = sb.indexOf("bbb");

		raf.seek(bbb);
		byte[] b1 = new byte[1024];
		StringBuilder sb1 = new StringBuilder((int) raf.length());
		while ((len = raf.read(b1)) != -1) {
			sb1.append(new String(b1, 0, len));
		}
		raf.seek(bbb);
		raf.write("***".getBytes());
		raf.write(sb1.toString().getBytes());
		raf.close();
	}

	@Test
	public void test2() throws IOException {
		String fileName = "D:\\Study\\IDEA\\vue\\Demo\\src\\io\\随机读写\\插入.txt";
		RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
		byte[] b = new byte[1024];
		StringBuilder sb = new StringBuilder((int) raf.length());
		int len;
		while ((len = raf.read(b)) != -1) {
			sb.append(new String(b, 0, len));
		}
		int bbb = sb.indexOf("bbb");

		raf.seek(bbb);
		byte[] b1 = new byte[1024];
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		while ((len = raf.read(b1)) != -1) {
			bos.write(b1, 0, len);
		}
		raf.seek(bbb);
		raf.write("***".getBytes());
		raf.write(bos.toString().getBytes());
		raf.close();
	}

}
